package com.geor.gcv.ict;

import java.io.File;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.nutz.json.Json;
import org.nutz.json.JsonField;
import org.nutz.json.ToJson;
import org.nutz.lang.Bytes;
import org.nutz.lang.Files;
import org.nutz.log.Loggers;
import org.nutz.repo.Base64;
import org.slf4j.Logger;

/**
 * int数组封装, 用于Set集合去重复
 * 
 * @author geor.yuli
 *
 */
@ToJson("dm")
public class DataMatrix {

	@JsonField("data")
	private int[] data;

	public DataMatrix() {
	}

	public DataMatrix(int[] data) {
		this.data = data;
	}

	public int[] getData() {
		return data;
	}

	public void setData(int[] data) {
		this.data = data;
	}

	/**
	 * 数据混淆
	 * 
	 * @param bytes
	 */
	public static void confuse(byte[] bytes) {
		for (int i = 0; i < bytes.length; i++) {
			bytes[i] = (byte) (bytes[i] ^ 0xff);
		}
	}

	static Logger log = Loggers.get();

	public static Map<String, Set<DataMatrix>> parsing(File file) {
		byte[] bytes = Files.readBytes(file);
		DataMatrix.confuse(bytes);
		try {
			Map<String, Set<DataMatrix>> datas = new HashMap<String, Set<DataMatrix>>();
			Map<String, Object> tmps = Json.fromJsonAsMap(Object.class, new String(bytes, "UTF-8"));
			for(String key : tmps.keySet()) {
				List<DataMatrix> dataMatrixs = (List<DataMatrix>) Json.fromJsonAsList(DataMatrix.class, tmps.get(key).toString().replaceAll("=", ":"));
				Set<DataMatrix> sets = new HashSet<DataMatrix>();
				for (DataMatrix dataMatrix : dataMatrixs) {
					sets.add(dataMatrix);
				}
				datas.put(key, sets);
			}
			log.info("load file " + file.getAbsolutePath());
			return datas;
		} catch (Exception e) {
			e.printStackTrace();
			log.info("skip file " + file.getAbsolutePath());
		}
		return new HashMap<String, Set<DataMatrix>>();
	}

	@Override
	public int hashCode() {
		byte[] bytes = new byte[4];
		for (int d : data) {
			bytes = Bytes.append(bytes, int2byte(d));
		}
		String code = Base64.encodeToString(bytes, false);
		return code.hashCode();
	}

	public byte[] int2byte(int res) {
		ByteBuffer buffer = ByteBuffer.allocate(4);
		buffer.asIntBuffer().put(res);
		return buffer.array();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof DataMatrix)) {
			return false;
		}
		DataMatrix other = (DataMatrix) obj;
		int[] otherdata = other.getData();
		for (int i = 0; i < data.length; i++) {
			if (data[i] != otherdata[i])
				return false;
		}
		return true;
	}

}
